use std::{net::Ipv4Addr, time::Duration};

use base_data::channel::{Channel, ChannelCallDirection, OriginateMsg};
use tokio::sync::mpsc;
use tools::{global_defin::tokio_runtime::get_rt, utils::network::combination_address_replace};
use tracing::{error, info, trace, warn};

use crate::{
	rtp::manager::{generate_rtp_listen, start_rtp_run_control},
	sdp::local_sdp,
	sip2::{
		dialog::dialog::dialog_id,
		manage::{listen_device, to_distribute},
		register::SipRegEvent,
		transport::TransportProtocol,
	},
	Dialog, DialogEvent,
};

#[test]
fn callout() {
	let rt = tools::global_defin::tokio_runtime::get_rt();
	let _rt_guard = rt.enter();
	let _log = tools::global_defin::trace_log::init_tracing_log();
	let _pool = &persistence::sqlx_p::DB.pool;

	listen_device(&handle_channel_start, &business_reg, |s| {
		Box::pin(user_login_sip_passwd_logic(s))
	});

	std::thread::park();
}

///根据给定用户名,返回相对应的密码.用于用户的sip注册
pub async fn user_login_sip_passwd_logic(name: &str) -> Option<String> {
	trace!("向数据库请求用户号码是否存在:{}", name);

	Some(name.to_owned())
}

pub fn handle_channel_start(channel: Channel) {
	match channel.direction() {
		ChannelCallDirection::InBound => info!("开始一个呼入"),
		ChannelCallDirection::OutBound => error!("目前还未开始处理呼出的业务逻辑"),
		ChannelCallDirection::UnknownValue => error!("未知的呼叫方向..无法处理"),
	}
}
pub fn business_reg(event: SipRegEvent) {
	match event {
		SipRegEvent::RegistSuccess(ev) => {
			tracing::info!("登录...{ev:?}");
			get_rt().spawn(async move {
				tokio::time::sleep(Duration::from_secs(4)).await;
				call_out_logic().await;
			});
		}
		SipRegEvent::RegistLoginOut(ev) => tracing::info!("登出操作...{ev:?}"),
		SipRegEvent::RegistFailure(ev) => tracing::info!("注册失败...{ev:?}"),
	}
}

pub async fn call_out_logic() {
	let (_s_d, r_d) = mpsc::channel(2048);
	let (s, _r) = mpsc::channel(2048);
	let (dist_t_dialog, dist_r_dialog) = mpsc::channel(2048);
	let dialog_id = dialog_id();

	let m = OriginateMsg {
		master_ch_id: 1,
		caller_num: "07916666661".to_owned(),
		called_num: "18179156296".to_owned(),
		caller_name: "07916666661".to_owned(),
		way: base_data::channel::OriginateWay::RegisterUser,
	};
	let transport = TransportProtocol::from_call_way(&m).await.unwrap();

	let ip = transport.local_addr().1.ip();
	let (rtp_sock, rtcp_sock) = generate_rtp_listen(ip).unwrap();
	warn!("ip:{:?}", ip);
	let mut sdp = local_sdp();
	sdp.set_addr(
		std::net::IpAddr::V4(Ipv4Addr::new(192, 168, 0, 99)),
		rtp_sock.local_addr().unwrap().port(),
		rtcp_sock.local_addr().unwrap().port(),
	);
	let dialog = Dialog::from_originate(
		dialog_id,
		&m,
		transport,
		r_d,
		dist_r_dialog,
		s,
		start_rtp_run_control(
			dialog_id,
			dist_t_dialog.clone(),
			combination_address_replace(sdp.c.address, &ip, sdp.first_rtp_port()),
			rtp_sock,
			rtcp_sock,
			&sdp.m,
		)
		.unwrap(),
		ip,
		&sdp,
	)
	.unwrap();

	let _ = to_distribute()
		.try_send(DialogEvent::NewDialog(dialog, dist_t_dialog))
		.unwrap();
}

#[test]
fn test_sdp() {}
